﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Globalization;

//http://www.w3.org/TR/ttaf1-dfxp/
//Timed Text Markup Language (TTML) 1.0
//W3C Recommendation 18 November 2010

namespace Nikse.SubtitleEdit.Logic.SubtitleFormats
{
    public class TimedText10 : SubtitleFormat
    {
        public override string Extension
        {
            get { return ".xml"; }
        }

        public override string Name
        {
            get { return "Timed Text 1.0"; }
        }

        public override bool IsTimeBased
        {
            get { return true; }
        }

        public override bool IsMine(List<string> lines, string fileName)
        {
            var sb = new StringBuilder();
            lines.ForEach(line => sb.AppendLine(line));
            string xmlAsString = sb.ToString().Trim();

            if (xmlAsString.Contains("xmlns:tts=\"http://www.w3.org/2006/04"))
                return false;

            if (xmlAsString.Contains("http://www.w3.org/ns/ttml"))
            {
                var xml = new XmlDocument();
                try
                {
                    xml.LoadXml(xmlAsString);
                    var nsmgr = new XmlNamespaceManager(xml.NameTable);
                    nsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml");
                    var nds = xml.DocumentElement.SelectSingleNode("ttml:body", nsmgr);
                    var paragraphs = nds.SelectNodes("//ttml:p", nsmgr);
                    return paragraphs.Count > 0;
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                }
            }
            return false;
        }

        internal static string ConvertToTimeString(TimeCode time)
        {
            if (string.IsNullOrEmpty(Configuration.Settings.SubtitleSettings.TimedText10TimeCodeFormat))
                return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
            else if (Configuration.Settings.SubtitleSettings.TimedText10TimeCodeFormat.Trim().ToLower() == "seconds")
                return string.Format(CultureInfo.InvariantCulture, "{0:0.0#}s", time.TotalSeconds);
            else if (Configuration.Settings.SubtitleSettings.TimedText10TimeCodeFormat.Trim().ToLower() == "milliseconds")
                return string.Format(CultureInfo.InvariantCulture, "{0}ms", time.TotalMilliseconds);
            else if (Configuration.Settings.SubtitleSettings.TimedText10TimeCodeFormat.Trim().ToLower() == "ticks")
                return string.Format(CultureInfo.InvariantCulture, "{0}t", TimeSpan.FromMilliseconds(time.TotalMilliseconds).Ticks);
            return string.Format("{0:00}:{1:00}:{2:00}:{3:00}", time.Hours, time.Minutes, time.Seconds, MillisecondsToFramesMaxFrameRate(time.Milliseconds));
        }

        public static void AddStyleToXml(XmlDocument xml, XmlNode head, XmlNamespaceManager nsmgr, string name, string fontFamily, string fontWeight, string fontStyle, string color, string fontSize)
        {
            var styleNode = xml.CreateNode(XmlNodeType.Element, string.Empty, "style", nsmgr.LookupNamespace("ttml"));

            XmlAttribute attr = xml.CreateAttribute("xml:id", "http://www.w3.org/ns/10/ttml#style");
            attr.InnerText = name;
            styleNode.Attributes.Append(attr);

            attr = xml.CreateAttribute("tts:fontFamily", "http://www.w3.org/ns/10/ttml#style");
            attr.InnerText = fontFamily;
            styleNode.Attributes.Append(attr);

            attr = xml.CreateAttribute("tts:fontWeight", "http://www.w3.org/ns/10/ttml#style");
            attr.InnerText = fontWeight;
            styleNode.Attributes.Append(attr);

            attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/10/ttml#style");
            attr.InnerText = fontStyle;
            styleNode.Attributes.Append(attr);

            attr = xml.CreateAttribute("tts:color", "http://www.w3.org/ns/10/ttml#style");
            attr.InnerText = color;
            styleNode.Attributes.Append(attr);

            attr = xml.CreateAttribute("tts:fontSize", "http://www.w3.org/ns/10/ttml#style");
            attr.InnerText = fontSize;
            styleNode.Attributes.Append(attr);

            foreach (XmlNode innerNode in head.ChildNodes)
            {
                if (innerNode.Name == "styling")
                {
                    innerNode.AppendChild(styleNode);
                    break;
                }
            }
        }

        public override string ToText(Subtitle subtitle, string title)
        {
            XmlNode styleHead = null;
            if (subtitle.Header != null)
            {
                try
                {
                    var x = new XmlDocument();
                    x.LoadXml(subtitle.Header);
                    var xnsmgr = new XmlNamespaceManager(x.NameTable);
                    xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml");
                    styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr);
                }
                catch
                {
                }
                if (styleHead == null && (subtitle.Header.Contains("[V4+ Styles]") || subtitle.Header.Contains("[V4 Styles]")))
                {
                    var x = new XmlDocument();
                    x.LoadXml(new TimedText10().ToText(new Subtitle(), "tt")); // load default xml
                    var xnsmgr = new XmlNamespaceManager(x.NameTable);
                    xnsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml");
                    styleHead = x.DocumentElement.SelectSingleNode("ttml:head", xnsmgr);
                    styleHead.SelectSingleNode("ttml:styling", xnsmgr).RemoveAll();
                    foreach (string styleName in AdvancedSubStationAlpha.GetStylesFromHeader(subtitle.Header))
                    {
                        try
                        {
                            var ssaStyle = AdvancedSubStationAlpha.GetSsaStyle(styleName, subtitle.Header);
                            if (ssaStyle != null)
                            {
                                string fontStyle = "normal";
                                if (ssaStyle.Italic)
                                    fontStyle = "italic";
                                string fontWeight = "normal";
                                if (ssaStyle.Bold)
                                    fontWeight = "bold";
                                AddStyleToXml(x, styleHead, xnsmgr, ssaStyle.Name, ssaStyle.FontName, fontWeight, fontStyle, Utilities.ColorToHex(ssaStyle.Primary), ssaStyle.FontSize.ToString());
                            }
                        }
                        catch
                        {
                        }
                    }
                    subtitle.Header = x.OuterXml; // save new xml with styles in header
                }
            }

            var xml = new XmlDocument();
            var nsmgr = new XmlNamespaceManager(xml.NameTable);
            nsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml");
            nsmgr.AddNamespace("ttp", "http://www.w3.org/ns/10/ttml#parameter");
            nsmgr.AddNamespace("tts", "http://www.w3.org/ns/10/ttml#style");
            nsmgr.AddNamespace("ttm", "http://www.w3.org/ns/10/ttml#metadata");
            string xmlStructure = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + Environment.NewLine +
            "<tt xmlns=\"http://www.w3.org/ns/ttml\" xmlns:ttp=\"http://www.w3.org/ns/ttml#parameter\" ttp:timeBase=\"media\" xmlns:tts=\"http://www.w3.org/ns/ttml#style\" xml:lang=\"en\" xmlns:ttm=\"http://www.w3.org/ns/ttml#metadata\">" + Environment.NewLine +
            "   <head>" + Environment.NewLine +
            "       <metadata>" + Environment.NewLine +
            "           <ttm:title></ttm:title>" + Environment.NewLine +
            "      </metadata>" + Environment.NewLine +
            "       <styling>" + Environment.NewLine +
            "         <style id=\"s0\" tts:backgroundColor=\"black\" tts:fontStyle=\"normal\" tts:fontSize=\"16\" tts:fontFamily=\"sansSerif\" tts:color=\"white\" />" + Environment.NewLine +
            "      </styling>" + Environment.NewLine +
            "   </head>" + Environment.NewLine +
            "   <body style=\"s0\">" + Environment.NewLine +
            "       <div />" + Environment.NewLine +
            "   </body>" + Environment.NewLine +
            "</tt>";
            if (styleHead == null)
            {
                xml.LoadXml(xmlStructure);
            }
            else
            {
                xml.LoadXml(subtitle.Header);
                XmlNode divNode = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).SelectSingleNode("ttml:div", nsmgr);
                if (divNode == null)
                    divNode = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).FirstChild;
                if (divNode != null)
                {
                    var lst = new List<XmlNode>();
                    foreach (XmlNode child in divNode.ChildNodes)
                        lst.Add(child);
                    foreach (XmlNode child in lst)
                        divNode.RemoveChild(child);
                }
                else
                {
                    xml.LoadXml(xmlStructure);
                }
            }


            XmlNode body = xml.DocumentElement.SelectSingleNode("ttml:body", nsmgr);
            string defaultStyle = Guid.NewGuid().ToString();
            if (body.Attributes["style"] != null)
                defaultStyle = body.Attributes["style"].InnerText;

            XmlNode div = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).SelectSingleNode("ttml:div", nsmgr);
            if (div == null)
                div = xml.DocumentElement.SelectSingleNode("//ttml:body", nsmgr).FirstChild;

            int no = 0;
            var headerStyles = GetStylesFromHeader(subtitle.Header);
            var languages = GetUsedLanguages(subtitle);
            if (languages.Count > 0)
            {
                foreach (Paragraph p in subtitle.Paragraphs)
                {
                    if (p.Language == null)
                    {
                        XmlNode paragraph = MakeParagraph(subtitle, xml, defaultStyle, no, headerStyles, p);
                        div.AppendChild(paragraph);
                        no++;
                    }
                }
                var divParentNode = div.ParentNode;
                if (div.ChildNodes.Count == 0)
                    divParentNode.RemoveChild(div);

                foreach (string language in languages)
                {
                    div = xml.CreateElement("div", "http://www.w3.org/ns/ttml");
                    XmlAttribute attr = xml.CreateAttribute("xml:lang", "http://www.w3.org/XML/1998/namespace");
                    attr.Value = language;
                    div.Attributes.Append(attr);
                    divParentNode.AppendChild(div);
                    foreach (Paragraph p in subtitle.Paragraphs)
                    {
                        if (p.Language == language)
                        {
                            XmlNode paragraph = MakeParagraph(subtitle, xml, defaultStyle, no, headerStyles, p);
                            div.AppendChild(paragraph);
                            no++;
                        }
                    }
                }
            }
            else
            {
                foreach (Paragraph p in subtitle.Paragraphs)
                {
                    XmlNode paragraph = MakeParagraph(subtitle, xml, defaultStyle, no, headerStyles, p);
                    div.AppendChild(paragraph);
                    no++;
                }
            }

            return ToUtf8XmlString(xml).Replace(" xmlns=\"\"", string.Empty).Replace(" xmlns:tts=\"http://www.w3.org/ns/10/ttml#style\">", ">");
        }

        private static XmlNode MakeParagraph(Subtitle subtitle, XmlDocument xml, string defaultStyle, int no, List<string> headerStyles, Paragraph p)
        {
            XmlNode paragraph = xml.CreateElement("p", "http://www.w3.org/ns/ttml");
            string text = p.Text;

            bool first = true;
            foreach (string line in text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
            {
                if (!first)
                {
                    XmlNode br = xml.CreateElement("br", "http://www.w3.org/ns/ttml");
                    paragraph.AppendChild(br);
                }

                System.Collections.Generic.Stack<XmlNode> styles = new Stack<XmlNode>();
                XmlNode currentStyle = xml.CreateTextNode(string.Empty);
                paragraph.AppendChild(currentStyle);
                int skipCount = 0;
                for (int i = 0; i < line.Length; i++)
                {
                    if (skipCount > 0)
                    {
                        skipCount--;
                    }
                    else if (line.Substring(i).StartsWith("<i>"))
                    {
                        styles.Push(currentStyle);
                        currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null);
                        paragraph.AppendChild(currentStyle);
                        XmlAttribute attr = xml.CreateAttribute("tts:fontStyle", "http://www.w3.org/ns/10/ttml#style");
                        attr.InnerText = "italic";
                        currentStyle.Attributes.Append(attr);
                        skipCount = 2;
                    }
                    else if (line.Substring(i).StartsWith("<b>"))
                    {
                        currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null);
                        paragraph.AppendChild(currentStyle);
                        XmlAttribute attr = xml.CreateAttribute("tts:fontWeight", "http://www.w3.org/ns/10/ttml#style");
                        attr.InnerText = "bold";
                        currentStyle.Attributes.Append(attr);
                        skipCount = 2;
                    }
                    else if (line.Substring(i).StartsWith("<font "))
                    {
                        int endIndex = line.Substring(i + 1).IndexOf(">");
                        if (endIndex > 0)
                        {
                            skipCount = endIndex + 1;
                            string fontContent = line.Substring(i, skipCount);
                            if (fontContent.Contains(" color="))
                            {
                                string[] arr = fontContent.Substring(fontContent.IndexOf(" color=") + 7).Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                                if (arr.Length > 0)
                                {
                                    string fontColor = arr[0].Trim('\'').Trim('"').Trim('\'');
                                    currentStyle = xml.CreateNode(XmlNodeType.Element, "span", null);
                                    paragraph.AppendChild(currentStyle);
                                    XmlAttribute attr = xml.CreateAttribute("tts:color", "http://www.w3.org/ns/10/ttml#style");
                                    attr.InnerText = fontColor;
                                    currentStyle.Attributes.Append(attr);
                                }
                            }
                        }
                        else
                        {
                            skipCount = line.Length;
                        }
                    }
                    else if (line.Substring(i).StartsWith("</i>") || line.Substring(i).StartsWith("</b>") || line.Substring(i).StartsWith("</font>"))
                    {
                        currentStyle = xml.CreateTextNode(string.Empty);
                        if (styles.Count > 0)
                        {
                            currentStyle = styles.Pop().CloneNode(true);
                            currentStyle.InnerText = string.Empty;
                        }
                        paragraph.AppendChild(currentStyle);
                        if (line.Substring(i).StartsWith("</font>"))
                            skipCount = 6;
                        else
                            skipCount = 3;
                    }
                    else
                    {
                        currentStyle.InnerText = currentStyle.InnerText + line.Substring(i, 1);
                    }
                }
                first = false;
            }

            XmlAttribute start = xml.CreateAttribute("begin");
            start.InnerText = ConvertToTimeString(p.StartTime);
            paragraph.Attributes.Append(start);

            XmlAttribute id = xml.CreateAttribute("id");
            id.InnerText = "p" + no.ToString();
            paragraph.Attributes.Append(id);

            XmlAttribute end = xml.CreateAttribute("end");
            end.InnerText = ConvertToTimeString(p.EndTime);
            paragraph.Attributes.Append(end);

            if (subtitle.Header != null && p.Style != null && headerStyles.Contains(p.Style))
            {
                if (p.Style != defaultStyle)
                {
                    XmlAttribute styleAttr = xml.CreateAttribute("style");
                    styleAttr.InnerText = p.Style;
                    paragraph.Attributes.Append(styleAttr);
                }
            }
            return paragraph;
        }

        public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
        {
            _errorCount = 0;
            double startSeconds = 0;

            var sb = new StringBuilder();
            lines.ForEach(line => sb.AppendLine(line));
            var xml = new XmlDocument();
            xml.LoadXml(sb.ToString().Trim());

            string ns = "http://www.w3.org/ns/ttml";
            var nsmgr = new XmlNamespaceManager(xml.NameTable);
            nsmgr.AddNamespace("ttml", ns);
            XmlNode body = xml.DocumentElement.SelectSingleNode("ttml:body", nsmgr);
            if (body == null)
                return;

            XmlAttribute frameRateAttr = xml.DocumentElement.Attributes["ttp:frameRate"];
            if (frameRateAttr != null)
            {
                double fr;
                if (double.TryParse(frameRateAttr.Value, out fr))
                    Configuration.Settings.General.CurrentFrameRate = fr;
            }

            subtitle.Header = sb.ToString();
            string defaultStyle = null;
            if (body.Attributes["style"] != null)
                defaultStyle = body.Attributes["style"].InnerText;
            foreach (XmlNode node in body.SelectNodes("//ttml:p", nsmgr))
            {
                try
                {
                    var pText = new StringBuilder();
                    foreach (XmlNode innerNode in node.ChildNodes)
                    {
                        switch (innerNode.Name)
                        {
                            case "br":
                                pText.AppendLine();
                                break;
                            case "span":
                                ReadSpan(pText, innerNode);
                                break;

                            default:
                                pText.Append(innerNode.InnerText);
                                break;
                        }
                    }

                    string start = string.Empty;
                    if (node.Attributes["begin"] != null)
                    {
                        start = node.Attributes["begin"].InnerText;
                    }
                    else if (node.Attributes["begin", ns] != null)
                    {
                        start = node.Attributes["begin", ns].InnerText;
                    }

                    string end = string.Empty;
                    if (node.Attributes["end"] != null)
                    {
                        end = node.Attributes["end"].InnerText;
                    }
                    else if (node.Attributes["end", ns] != null)
                    {
                        end = node.Attributes["end", ns].InnerText;
                    }

                    string dur = string.Empty;
                    if (node.Attributes["dur"] != null)
                    {
                        dur = node.Attributes["dur"].InnerText;
                    }
                    else if (node.Attributes["dur", ns] != null)
                    {
                        dur = node.Attributes["dur", ns].InnerText;
                    }

                    var startCode = new TimeCode(TimeSpan.FromSeconds(startSeconds));
                    if (start.Length > 0)
                    {
                        startCode = GetTimeCode(start, true);
                    }

                    TimeCode endCode;
                    if (end.Length > 0)
                    {
                        endCode = GetTimeCode(end, true);
                    }
                    else if (dur.Length > 0)
                    {
                        endCode = new TimeCode(TimeSpan.FromMilliseconds(GetTimeCode(dur, true).TotalMilliseconds + startCode.TotalMilliseconds));
                    }
                    else
                    {
                        endCode = new TimeCode(TimeSpan.FromMilliseconds(startCode.TotalMilliseconds + 3000));
                    }
                    startSeconds = endCode.TotalSeconds;

                    var p = new Paragraph(startCode, endCode, pText.ToString().Replace("   ", " ").Replace("  ", " "));
                    p.Style = defaultStyle;
                    if (node.Attributes["style"] != null)
                        p.Style = node.Attributes["style"].InnerText;

                    if (node.Attributes["region"] != null)
                    {
                        string region = node.Attributes["region"].Value;
                        if (region == "top")
                            p.Text = "{\\an8}" + p.Text;
                    }

                    // check language
                    if (node.ParentNode.Name == "div")
                    {
                        if (node.ParentNode.Attributes["xml:lang"] != null)
                            p.Language = node.ParentNode.Attributes["xml:lang"].InnerText;
                        else if (node.ParentNode.Attributes["lang"] != null)
                            p.Language = node.ParentNode.Attributes["lang"].InnerText;
                    }

                    p.Extra = SetExtra(p);

                    subtitle.Paragraphs.Add(p);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                    _errorCount++;
                }
            }
            subtitle.Renumber(1);
        }

        public static string SetExtra(Paragraph p)
        {
            string style = p.Style;
            if (string.IsNullOrEmpty(style))
                style = "-";
            string lang = p.Language;
            if (string.IsNullOrEmpty(lang))
                lang = "-";
            return string.Format("{0} / {1}", style, lang);
        }

        private static void ReadSpan(StringBuilder pText, XmlNode innerNode)
        {
            bool italic = false;
            bool font = false;
            bool bold = false;
            if (innerNode.Attributes != null)
            {
                var fs = innerNode.Attributes.GetNamedItem("tts:fontStyle");
                if (fs != null && fs.Value == "italic")
                {
                    italic = true;
                    pText.Append("<i>");
                }

                var fc = innerNode.Attributes.GetNamedItem("tts:color");
                if (fc != null && fc.Value.Length > 0)
                {
                    pText.Append("<font color=\"" + fc.Value + "\">");
                    font = true;
                }

                var fw = innerNode.Attributes.GetNamedItem("tts:fontWeight");
                if (fw != null && fs.Value == "bold")
                {
                    pText.Append("<b>");
                    bold = true;
                }
            }
            if (innerNode.HasChildNodes)
            {
                foreach (XmlNode innerInnerNode in innerNode.ChildNodes)
                {
                    if (innerInnerNode.Name == "br")
                    {
                        pText.AppendLine();
                    }
                    else if (innerInnerNode.Name == "span")
                    {
                        ReadSpan(pText, innerInnerNode);
                    }
                    else
                    {
                        pText.Append(innerInnerNode.InnerText);
                    }
                }
            }
            else
            {
                pText.Append(innerNode.InnerText);
            }
            if (italic)
                pText.Append("</i>");
            if (font)
                pText.Append("</font>");
            if (bold)
                pText.Append("</bold>");
        }

        public static TimeCode GetTimeCode(string s, bool frames)
        {
            if (s.EndsWith("ms"))
            {
                s = s.TrimEnd('s');
                s = s.TrimEnd('m');
                TimeSpan ts = TimeSpan.FromMilliseconds(double.Parse(s.Replace(",", "."), System.Globalization.CultureInfo.InvariantCulture));
                return new TimeCode(ts);
            }
            else if (s.EndsWith("s"))
            {
                s = s.TrimEnd('s');
                TimeSpan ts = TimeSpan.FromSeconds(double.Parse(s.Replace(",", "."), System.Globalization.CultureInfo.InvariantCulture));
                return new TimeCode(ts);
            }
            else if (s.EndsWith("t"))
            {
                s = s.TrimEnd('t');
                TimeSpan ts = TimeSpan.FromTicks(long.Parse(s, System.Globalization.CultureInfo.InvariantCulture));
                return new TimeCode(ts);
            }
            string[] parts = s.Split(new[] { ':', '.', ',' });
            if (frames)
                return new TimeCode(new TimeSpan(0, int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]), FramesToMillisecondsMax999(int.Parse(parts[3]))));
            return new TimeCode(new TimeSpan(0, int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]), int.Parse(parts[3])));
        }

        public override List<string> AlternateExtensions
        {
            get
            {
                return new List<string>() { ".itt", ".dfxp" }; // iTunes Timed Text + ...
            }
        }

        public override bool HasStyleSupport
        {
            get
            {
                return true;
            }
        }

        public static List<string> GetStylesFromHeader(string xmlAsString)
        {
            var list = new List<string>();
            var xml = new XmlDocument();
            try
            {
                xml.LoadXml(xmlAsString);
                var nsmgr = new XmlNamespaceManager(xml.NameTable);
                nsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml");
                XmlNode head = xml.DocumentElement.SelectSingleNode("ttml:head", nsmgr);
                foreach (XmlNode node in head.SelectNodes("//ttml:style", nsmgr))
                {
                    if (node.Attributes["xml:id"] != null)
                        list.Add(node.Attributes["xml:id"].Value);
                    else if (node.Attributes["id"] != null)
                        list.Add(node.Attributes["id"].Value);
                }
            }
            catch
            {
            }
            return list;
        }

        public static List<string> GetRegionsFromHeader(string xmlAsString)
        {
            var list = new List<string>();
            var xml = new XmlDocument();
            try
            {
                xml.LoadXml(xmlAsString);
                var nsmgr = new XmlNamespaceManager(xml.NameTable);
                nsmgr.AddNamespace("ttml", "http://www.w3.org/ns/ttml");
                XmlNode head = xml.DocumentElement.SelectSingleNode("ttml:head", nsmgr);
                foreach (XmlNode node in head.SelectNodes("//ttml:region", nsmgr))
                {
                    if (node.Attributes["xml:id"] != null)
                        list.Add(node.Attributes["xml:id"].Value);
                    else if (node.Attributes["id"] != null)
                        list.Add(node.Attributes["id"].Value);
                }
            }
            catch
            {
            }
            return list;
        }

        public static List<string> GetUsedLanguages(Subtitle subtitle)
        {
            var list = new List<string>();
            foreach (Paragraph p in subtitle.Paragraphs)
            {
                if (p.Language != null)
                {
                    string l = p.Language.ToLower().Trim();
                    if (!list.Contains(l))
                        list.Add(l);
                }
            }
            return list;
        }

    }
}


